#ifndef UTILS_H
#define UTILS_H

#include <stdint.h>
#include <errno.h>
#include <string.h>
#include <stdio.h>

#include <list>
#include <vector>
#include <string>
#include <map>
#include <sstream>
#include <unistd.h>
#include <linux/param.h>

#include "core.h"

/**
 * @brief readlink 读取符号链接所指向的真实路径
 * @param path 符号链接路径，本函数只接受绝对路径
 * @return 真实路径
 */
extern std::string
readlink(const char *path);

extern std::string
readlink(const std::string &path);

/**
 * @brief trim 去掉字符串两边的空白字符
 * @param s 待处理字符串
 * @return 处理结果为新的字符串
 */
extern std::string
trim(const std::string &s);

class NoSuchFile {};

/**
 * @brief loadFile 把一个文件的内容载入到字符串
 * @param path 要载入的文件路径
 * @return 保存文件内容的字符串
 */
extern std::string
getFileContent(const char *path);

extern std::string
getFileContent(const std::string &path);

extern inline time_t
jiffies_to_sec(jiffies_t jiffies)
{
    return jiffies / HZ;
}

class Properties
{
private:
    std::vector<std::string> names;
    std::map<std::string, std::string> map;

public:

    typedef std::vector<std::string>::size_type size_type;


    /**
     * @brief load 把字符串解析为属性集合，
     * 字符串中含有若干行，如果一行中含有冒号，
     * 则以第一个冒号为分界把这一行解析为一个键值对，
     * 一个键值对也就是一个属性，键为属性名，值为属性值，
     * 以map的形式表示属性集合。
     * @param s 待解析字符串
     */
    void loadFromText(const std::string &s);

    /**
     * @brief loadFile 从文件载入属性集
     * @param path 文件路径
     */
    void loadFromFile(const char *path);

    /**
     * @brief size 查询属性数量
     * @return 属性数量
     */
    size_type size() const {
        return names.size();
    }

    bool contains(const std::string &name) const {
        return map.find(name) != map.end();
    }

    std::string getName(size_type pos) const {
        if (pos >= names.size()) {
            ERROR("out of bounds haha");
        }
        return names[pos];
    }

    std::string value(const std::string &name) const {
        std::map<std::string, std::string>::const_iterator iter;
        iter = map.find(name);
        if (iter != map.end()) {
            return iter->second;
        } else {
            ERROR("name not found");
        }
    }
};

#endif // UTILS_H

